#include <zmq.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "ipc.h"

GMainLoop *loop;
GData *signal_dispatch_map;


void broadcast_signal(GQuark key_id, gpointer data, gpointer user_data) 
{
	GVariant *var = user_data;
	const char *name = g_quark_to_string(key_id);
	GVariant *ret;
	g_variant_ref(var);
	ret = ipc_call((char*)name, "_Sig", var);
	g_variant_unref(ret);
}

GVariant *raise_signal(GVariant *par)
{
	gchar *daemon, *func;
	GVariant *var;
	GData *tmp = NULL;
	GString *str = g_string_new("");
	//char *buf;
	//buf = g_variant_print(par, FALSE);

	g_variant_get(par, "(&s&sv)", &daemon, &func, &var);
	g_string_printf(str, "%s %s", daemon, func);

	tmp = g_datalist_get_data(&signal_dispatch_map, str->str);
	if ( tmp ) {
		g_datalist_foreach(&tmp, broadcast_signal, par);
	}
	

	g_string_free(str, TRUE);
	g_variant_unref(var);
	//printf("%s\n", buf);
	//free(buf);
	return g_variant_new("(b)", TRUE);
}

GVariant *reg_signal(GVariant *par)
{
	gchar *target, *daemon, *func;
	GString *str = g_string_new("");
	GData *tmp = NULL;

	g_variant_get(par, "(&s&s&s)", &target, &daemon, &func);
	g_string_printf(str, "%s %s", daemon, func);

	tmp = g_datalist_get_data(&signal_dispatch_map, str->str);
	if (tmp == NULL) {
		g_datalist_init(&tmp);
	}
	g_datalist_set_data(&tmp, target, GINT_TO_POINTER(1)); /*signal_dispatch_map is meaningless here.*/
	g_datalist_set_data(&signal_dispatch_map, str->str, tmp);

	g_string_free(str, TRUE);

	return g_variant_new("(b)", TRUE);
}

int main (void)
{
	ipc_init("libcpcd");
	g_datalist_init(&signal_dispatch_map);
	ipc_add("RegSignal", reg_signal, "(sss)", "(b)");
	ipc_add("RaiseSignal", raise_signal, "(ssv)", "(b)");
	loop = g_main_loop_new(NULL, FALSE);


	g_main_loop_run(loop);
	ipc_release();
	return 0;
}
